#include "api_User.h"

#include <drogon/orm/CoroMapper.h>

#include "models/TUser.h"
#include "utils/response.h"
#include "utils/password.h"
#include "utils/jwt.h"

using namespace api;
using namespace drogon;
using namespace orm;
using namespace drogon_model::chat_room;

/**
 * 将参数转换成json
 * @return json参数
 */
Json::Value params::UserParams::toJson() const {
    Json::Value json;
    json["account"] = account;
    json["password"] = password;
    return json;
}

/**
 * 将参数转换成json
 * @return json参数
 */
Json::Value params::LoginParams::toJson() const {
    return UserParams::toJson();
}

/**
 * 将参数转换成json
 * @return json参数
 */
Json::Value params::RegisterParams::toJson() const {
    auto json = UserParams::toJson();
    json["username"] = username;
    return json;
}

/**
 * 登录
 * @param req 请求对象指针
 * @param params 登陆参数
 * @return http响应对象指针
 */
Task<HttpResponsePtr> User::login([[maybe_unused]] HttpRequestPtr req, params::LoginParams params) {
    // 获取数据库连接
    auto conn = drogon::app().getFastDbClient();
    // 创建mapper
    auto mapper = CoroMapper<TUser>(conn);

    try {
        // 查询用户
        auto user = co_await mapper.findOne(Criteria(TUser::Cols::_account, CompareOperator::EQ, params.account));
        // 检查密码是否正确
        if (!verify_password(params.password, user.getValueOfPassword())) {
            // 返回密码错误
            co_return HttpResponse::newHttpJsonResponse(response::WrongPasswordResponse());
        }
        // 创建一个新的JWT令牌
        auto token = Jwt::createToken(user.toJson());
        // 返回成功响应
        co_return HttpResponse::newHttpJsonResponse(response::SuccessResponse(token));
    } catch ([[maybe_unused]] const std::exception &e) {
        // 返回包含错误信息的响应
        co_return HttpResponse::newHttpJsonResponse(response::UserDoesNotExistResponse());
    }
}

/**
 * 注册
 * @param req 请求对象指针
 * @param params 注册参数
 * @return http响应对象指针
 */
Task<HttpResponsePtr> User::register_([[maybe_unused]] HttpRequestPtr req, params::RegisterParams params) {
    // 创建 orm 对象
    auto user = TUser(params.toJson());
    // 获取数据库连接
    auto conn = drogon::app().getFastDbClient();
    // 获取事务
    auto trans = co_await conn->newTransactionCoro();
    // 创建mapper
    auto mapper = CoroMapper<TUser>(trans);

    try {
        // 检查账户是否已经存在
        auto existingUserCount = co_await mapper.count(
                Criteria(TUser::Cols::_account, CompareOperator::EQ, params.account));
        // 如果数量大于零
        if (existingUserCount > 0) {
            // 回滚事务
            trans->rollback();
            // 返回包含错误信息的响应
            co_return HttpResponse::newHttpJsonResponse(response::UserExistsResponse());
        }

        // 插入数据
        co_await mapper.insert(user);
    } catch (const std::exception &e) {
        // 回滚事务
        trans->rollback();

        // 返回包含错误信息的响应
        co_return HttpResponse::newHttpJsonResponse(
                response::ErrorResponse(e.what(), response::StatusCode::UserExists));
    }
    // 返回成功响应
    co_return HttpResponse::newHttpJsonResponse(response::SuccessResponse());
}

